const path = require('path');
const fs = require('fs');
const { PDFDocument, rgb } = require('pdf-lib');
const fontkit = require('@pdf-lib/fontkit');
const mammoth = require('mammoth');
const { Document, Packer, Paragraph } = require('docx');
const { htmlToText } = require('html-to-text');
const iconv = require('iconv-lite');
const JSZip = require('jszip');

// 存储转换进度
const conversionProgress = new Map();

// 加载中文字体
async function loadChineseFont() {
  try {
    // 优先使用TTF格式字体
    const fontPaths = [
      'C:\\Windows\\Fonts\\simsun.ttf',  // 宋体
      'C:\\Windows\\Fonts\\simhei.ttf',  // 黑体
      'C:\\Windows\\Fonts\\simkai.ttf',  // 楷体
      'C:\\Windows\\Fonts\\simfang.ttf', // 仿宋
      'C:\\Windows\\Fonts\\msyh.ttf',    // 微软雅黑
      'C:\\Windows\\Fonts\\STKAITI.TTF', // 华文楷体
      'C:\\Windows\\Fonts\\STXIHEI.TTF'  // 华文细黑
    ];
    
    for (const fontPath of fontPaths) {
      if (fs.existsSync(fontPath)) {
        console.log('使用字体:', fontPath);
        const fontBytes = fs.readFileSync(fontPath);
        // 验证字体文件
        if (fontBytes.length > 0) {
          return fontBytes;
        }
      }
    }
    
    throw new Error('未找到可用的中文TTF字体文件');
  } catch (error) {
    console.error('加载字体错误:', error);
    throw error;
  }
}

const fileController = {
  // 文件上传
  async uploadFile(req, res) {
    try {
      if (!req.file) {
        return res.status(400).json({ error: '没有上传文件' });
      }

      const sourceFile = req.file;
      const sourceExt = path.extname(sourceFile.originalname).toLowerCase();
      const fileId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
      
      // 将文件信息存储在 Map 中
      const fileInfo = {
        originalName: sourceFile.originalname,
        path: sourceFile.path,
        sourceExt,
        status: 'uploaded',
        convertedFiles: [] // 存储所有转换后的文件路径
      };
      conversionProgress.set(fileId, fileInfo);

      res.json({
        success: true,
        fileId,
        message: '文件上传成功',
        sourceExt,
        originalName: sourceFile.originalname
      });

    } catch (error) {
      console.error('文件上传错误:', error);
      res.status(500).json({ error: error.message || '文件上传失败' });
    }
  },

  // 文件转换
  async convertFile(req, res) {
    try {
      const { fileId, targetFormat } = req.body;
      
      if (!fileId || !targetFormat) {
        return res.status(400).json({ error: '缺少必要参数' });
      }

      const fileInfo = conversionProgress.get(fileId);
      if (!fileInfo) {
        return res.status(404).json({ error: '找不到上传的文件' });
      }

      // 检查源文件是否存在
      if (!fs.existsSync(fileInfo.path)) {
        return res.status(404).json({ error: '源文件不存在' });
      }

      const conversionKey = `${fileInfo.sourceExt}_to_${targetFormat}`.toLowerCase();
      console.log('转换类型:', conversionKey);

      let outputPath;
      switch(conversionKey) {
        case '.txt_to_.pdf':
          outputPath = await convertTxtToPdf(fileInfo.path, fileId);
          break;
        case '.docx_to_.pdf':
        case '.doc_to_.pdf':
          outputPath = await convertDocToPdf(fileInfo.path, fileId);
          break;
        case '.txt_to_.docx':
          outputPath = await convertTxtToDoc(fileInfo.path, fileId);
          break;
        case '.pdf_to_.txt':
          outputPath = await convertPdfToTxt(fileInfo.path, fileId);
          break;
        case '.docx_to_.txt':
        case '.doc_to_.txt':
          outputPath = await convertDocToTxt(fileInfo.path, fileId);
          break;
        default:
          console.log('不支持的转换:', {
            sourceExt: fileInfo.sourceExt,
            targetFormat,
            conversionKey
          });
          throw new Error(`不支持的转换格式: ${fileInfo.sourceExt} -> ${targetFormat}`);
      }

      // 检查转换后的文件是否存在且不为空
      if (!fs.existsSync(outputPath) || fs.statSync(outputPath).size === 0) {
        throw new Error('文件转换失败，输出文件为空');
      }

      // 更新文件信息
      fileInfo.status = 'converted';
      fileInfo.outputPath = outputPath;
      fileInfo.convertedFiles.push(outputPath);
      conversionProgress.set(fileId, fileInfo);

      res.json({
        success: true,
        message: '文件转换成功',
        outputPath: path.basename(outputPath)
      });

    } catch (error) {
      console.error('文件转换错误:', error);
      res.status(500).json({ error: error.message || '文件转换失败' });
    }
  },

  // 获取转换进度
  getProgress(req, res) {
    const { id } = req.params;
    const fileInfo = conversionProgress.get(id);
    if (!fileInfo) {
      return res.status(404).json({ error: '找不到文件信息' });
    }
    res.json({
      status: fileInfo.status,
      progress: fileInfo.status === 'converted' ? 100 : 0
    });
  },

  // 下载转换后的文件
  downloadFile(req, res) {
    const { filename } = req.params;
    const filePath = path.join(__dirname, '../../uploads', filename);

    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ error: '文件不存在' });
    }

    // 检查文件是否为空
    if (fs.statSync(filePath).size === 0) {
      return res.status(400).json({ error: '文件内容为空' });
    }

    res.download(filePath, filename, (err) => {
      if (err) {
        res.status(500).json({ error: '下载文件失败' });
      } else {
        // 下载完成后延迟删除文件
        setTimeout(() => {
          try {
            const fileInfo = Array.from(conversionProgress.values())
              .find(info => info.path === filePath || info.convertedFiles.includes(filePath));
            
            if (fileInfo) {
              // 只删除当前下载的文件，保留其他文件
              if (fs.existsSync(filePath)) {
                fs.unlinkSync(filePath);
              }
              
              // 从convertedFiles中移除已删除的文件
              fileInfo.convertedFiles = fileInfo.convertedFiles.filter(f => f !== filePath);
              
              // 如果没有剩余的转换文件且源文件已下载，则删除整个记录
              if (fileInfo.convertedFiles.length === 0 && !fs.existsSync(fileInfo.path)) {
                for (const [key, value] of conversionProgress.entries()) {
                  if (value === fileInfo) {
                    conversionProgress.delete(key);
                    break;
                  }
                }
              }
            }
          } catch (error) {
            console.error('清理文件错误:', error);
          }
        }, 1000);
      }
    });
  }
};

// 转换函数
async function convertTxtToPdf(inputPath, jobId) {
  try {
    // 读取文本文件内容
    const text = iconv.decode(fs.readFileSync(inputPath), 'utf8');
    
    // 创建PDF文档
    const pdfDoc = await PDFDocument.create();
    
    // 注册fontkit
    pdfDoc.registerFontkit(fontkit);
    
    // 创建页面
    const page = pdfDoc.addPage([595.276, 841.890]); // A4尺寸
    
    try {
      // 加载并嵌入中文字体
      const fontBytes = await loadChineseFont();
      const chineseFont = await pdfDoc.embedFont(fontBytes, { subset: true });
      
      // 设置页面参数
      const fontSize = 12;
      const lineHeight = fontSize * 1.5;
      const margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      };
      const pageWidth = page.getWidth();
      const pageHeight = page.getHeight();
      const maxWidth = pageWidth - margin.left - margin.right;
      
      // 分割文本为行
      const words = text.split('');
      let lines = [''];
      let currentLine = 0;
      let currentY = pageHeight - margin.top;
      let currentPage = page;
      
      for (const word of words) {
        const currentWidth = chineseFont.widthOfTextAtSize(lines[currentLine] + word, fontSize);
        if (currentWidth <= maxWidth) {
          lines[currentLine] += word;
        } else {
          currentLine++;
          lines[currentLine] = word;
          
          // 检查是否需要新页面
          if (currentY - lineHeight < margin.bottom) {
            currentPage = pdfDoc.addPage([595.276, 841.890]);
            currentY = pageHeight - margin.top;
          }
        }
      }
      
      // 绘制文本
      let pageIndex = 0;
      currentY = pageHeight - margin.top;
      currentPage = page;
      
      for (const line of lines) {
        if (currentY - lineHeight < margin.bottom) {
          pageIndex++;
          currentPage = pdfDoc.addPage([595.276, 841.890]);
          currentY = pageHeight - margin.top;
        }
        
        currentPage.drawText(line, {
          x: margin.left,
          y: currentY,
          size: fontSize,
          font: chineseFont,
          color: rgb(0, 0, 0),
          lineHeight: lineHeight
        });
        
        currentY -= lineHeight;
      }
      
    } catch (fontError) {
      console.error('字体加载错误，使用ASCII字符创建PDF:', fontError);
      
      // 如果字体加载失败，使用ASCII字符创建PDF
      const fontSize = 12;
      const lineHeight = fontSize * 1.5;
      const margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      };
      const maxWidth = page.getWidth() - margin.left - margin.right;
      
      // 将文本转换为ASCII字符
      const asciiText = text.replace(/[^\x00-\x7F]/g, '?');
      const words = asciiText.split(/\s+/);
      let lines = [];
      let currentLine = '';
      
      for (const word of words) {
        if (currentLine.length * fontSize * 0.6 > maxWidth) {
          lines.push(currentLine.trim());
          currentLine = word;
        } else {
          currentLine += (currentLine ? ' ' : '') + word;
        }
      }
      if (currentLine) {
        lines.push(currentLine.trim());
      }
      
      // 绘制ASCII文本
      let currentY = page.getHeight() - margin.top;
      let currentPage = page;
      
      for (const line of lines) {
        if (currentY - lineHeight < margin.bottom) {
          currentPage = pdfDoc.addPage([595.276, 841.890]);
          currentY = currentPage.getHeight() - margin.top;
        }
        
        currentPage.drawText(line, {
          x: margin.left,
          y: currentY,
          size: fontSize,
          color: rgb(0, 0, 0)
        });
        
        currentY -= lineHeight;
      }
    }
    
    // 保存PDF
    const outputPath = inputPath.replace('.txt', '.pdf');
    const pdfBytes = await pdfDoc.save();
    fs.writeFileSync(outputPath, pdfBytes);
    
    // 更新进度
    conversionProgress.set(jobId, 100);
    
    return outputPath;
  } catch (error) {
    console.error('转换错误:', error);
    throw error;
  }
}

async function convertDocToPdf(inputPath, jobId) {
  try {
    // 使用mammoth转换DOCX为HTML
    const result = await mammoth.convertToHtml({ path: inputPath });
    if (!result.value) {
      throw new Error('文档内容转换失败');
    }
    
    const html = result.value;
    
    // 创建PDF文档
    const pdfDoc = await PDFDocument.create();
    pdfDoc.registerFontkit(fontkit);
    
    // 创建页面
    const page = pdfDoc.addPage([595.276, 841.890]); // A4尺寸
    
    try {
      // 加载并嵌入中文字体
      const fontBytes = await loadChineseFont();
      const chineseFont = await pdfDoc.embedFont(fontBytes, { subset: true });
      
      // 将HTML转换为纯文本，保留格式
      const text = htmlToText(html, {
        wordwrap: 130,
        selectors: [
          { selector: 'img', format: 'skip' },
          { selector: 'a', options: { ignoreHref: true } },
          { selector: 'p', format: 'paragraph' },
          { selector: 'br', format: 'linebreak' }
        ],
        preserveNewlines: true
      });
      
      if (!text || text.trim().length === 0) {
        throw new Error('转换后的文本内容为空');
      }
      
      // 设置页面参数
      const fontSize = 12;
      const lineHeight = fontSize * 1.5;
      const margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      };
      const maxWidth = page.getWidth() - margin.left - margin.right;
      
      // 分割文本为行，保留段落格式
      const paragraphs = text.split('\n\n');
      let currentY = page.getHeight() - margin.top;
      let currentPage = page;
      
      for (const paragraph of paragraphs) {
        const lines = paragraph.split('\n');
        
        for (const line of lines) {
          if (currentY - lineHeight < margin.bottom) {
            currentPage = pdfDoc.addPage([595.276, 841.890]);
            currentY = currentPage.getHeight() - margin.top;
          }
          
          if (line.trim().length > 0) {
            currentPage.drawText(line.trim(), {
              x: margin.left,
              y: currentY,
              size: fontSize,
              font: chineseFont,
              color: rgb(0, 0, 0)
            });
          }
          
          currentY -= lineHeight;
        }
        
        // 段落间额外间距
        currentY -= lineHeight;
      }
      
    } catch (fontError) {
      console.error('字体加载错误，使用ASCII字符创建PDF:', fontError);
      // 使用基本ASCII字符回退方案
      const text = htmlToText(html, { 
        wordwrap: 130,
        preserveNewlines: true
      });
      
      if (!text || text.trim().length === 0) {
        throw new Error('转换后的ASCII文本内容为空');
      }
      
      const fontSize = 12;
      const lineHeight = fontSize * 1.5;
      const margin = 50;
      
      const lines = text.split('\n');
      let currentY = page.getHeight() - margin;
      let currentPage = page;
      
      for (const line of lines) {
        if (currentY - lineHeight < margin) {
          currentPage = pdfDoc.addPage([595.276, 841.890]);
          currentY = currentPage.getHeight() - margin;
        }
        
        if (line.trim().length > 0) {
          currentPage.drawText(line.trim(), {
            x: margin,
            y: currentY,
            size: fontSize,
            color: rgb(0, 0, 0)
          });
        }
        
        currentY -= lineHeight;
      }
    }
    
    const outputPath = inputPath.replace(/\.(docx?)/i, '.pdf');
    const pdfBytes = await pdfDoc.save();
    
    // 验证生成的PDF
    if (!pdfBytes || pdfBytes.length === 0) {
      throw new Error('生成的PDF内容为空');
    }
    
    fs.writeFileSync(outputPath, pdfBytes);
    
    // 验证写入的文件
    if (!fs.existsSync(outputPath) || fs.statSync(outputPath).size === 0) {
      throw new Error('PDF文件写入失败');
    }
    
    conversionProgress.set(jobId, 100);
    return outputPath;
  } catch (error) {
    console.error('转换错误:', error);
    throw error;
  }
}

async function convertTxtToDoc(inputPath, jobId) {
  try {
    // 读取文本内容
    const text = iconv.decode(fs.readFileSync(inputPath), 'utf8');
    if (!text || text.trim().length === 0) {
      throw new Error('源文件内容为空');
    }
    
    // 创建新的Word文档
    const doc = new Document({
      sections: [{
        properties: {
          page: {
            size: {
              width: 11906,  // A4宽度 (210mm)
              height: 16838  // A4高度 (297mm)
            },
            margin: {
              top: 1440,    // 1英寸 = 1440 twips
              right: 1440,
              bottom: 1440,
              left: 1440
            }
          }
        },
        children: text.split('\n').map(line => 
          new Paragraph({
            children: [{ 
              text: line || ' ', // 确保空行也能正确显示
              size: 24, // 12pt
              font: 'SimSun'
            }],
            spacing: {
              line: 360, // 1.5倍行距
              before: 0,
              after: 0
            }
          })
        )
      }]
    });

    const outputPath = inputPath.replace('.txt', '.docx');
    const buffer = await Packer.toBuffer(doc);
    
    // 验证生成的文件
    if (!buffer || buffer.length === 0) {
      throw new Error('生成的文档内容为空');
    }
    
    fs.writeFileSync(outputPath, buffer);
    
    // 验证写入的文件
    if (!fs.existsSync(outputPath) || fs.statSync(outputPath).size === 0) {
      throw new Error('文件写入失败');
    }
    
    conversionProgress.set(jobId, 100);
    return outputPath;
  } catch (error) {
    console.error('转换错误:', error);
    throw error;
  }
}

async function convertPdfToTxt(inputPath, jobId) {
  const pdfBytes = fs.readFileSync(inputPath);
  const pdfDoc = await PDFDocument.load(pdfBytes);
  let text = '';
  
  for (let i = 0; i < pdfDoc.getPageCount(); i++) {
    const page = pdfDoc.getPage(i);
    text += await page.getText() + '\n';
    conversionProgress.set(jobId, Math.floor((i + 1) / pdfDoc.getPageCount() * 100));
  }

  const outputPath = inputPath.replace('.pdf', '.txt');
  fs.writeFileSync(outputPath, text);
  return outputPath;
}

async function convertDocToTxt(inputPath, jobId) {
  const result = await mammoth.extractRawText({ path: inputPath });
  const outputPath = inputPath.replace(/\.(docx?)/i, '.txt');
  fs.writeFileSync(outputPath, result.value);
  
  conversionProgress.set(jobId, 100);
  return outputPath;
}

module.exports = fileController; 